O K8S
Este texto nasceu após o meu primeiro k8s de produção, sem antes ter feito em bancada, como a curva de aprendizado foi rápida, decidi montar um lab baseado na experiencia que tive, documentando a montagem de um cluster multimaster em Ubuntu 22.04 usando containerd, Calico, MetalLB e ingress-nginx
Os possas seguidos aqui, podem facilmente ser replicados para produção.
Requisitos base
3 mastergarante quórum no etcd e alta disponibilidade do plano de controle: se um nó cair, os outros dois ainda formam maioria e mantêm o cluster operante.
2 workerpara garantir um cluster altamente disponivel, um worker pode parar que o outro continua servindo aplicações.
O mínimo a ser feito
Quando comento com o mínimo, me refiro ao básico que precisa ser feito para que comecemos a instalação e configuração do k8s, seguindo um processo lógico/pratico.
- Configurar ntpd
- Configurar SSSD (integração com AD ou LDAP)se tiver
- Configurar agente de monitoramentose tiver
- SSH
- Sudoers
- Grupos
- Usuários
- Permissões
Preparando o Linux
Dividi em três seções:
- Passos para todos os nós
- Passos para os masters
- Passos para os workers
Passos para todos os nós
Verificar MAC address: Não pode ter mac duplicado
ip link show
Verificar UUID da máquina: Assim como o mac o UUID da maquinda deve ser unico
cat /etc/machine-id
Caso tenha duplicidade, basta executar para regerar:
rm -f /etc/machine-id
systemd-machine-id-setup
Desativar o swap:
# Verificando
swapon -s
# Desativando
sudo swapoff -a
# Removendo do fstab
sudo sed -i '/swap/d' /etc/fstab
para utilizar a swap, necessário configurar seguinte parâmetro:
No kubelet (/etc/default/kubelet), adicionar
failSwapOn: false
ou configurarswapBehavior
.
Se tiver um arquivo /swap.img
no sistema, apague também, pois isso é um arquivo e ocupa bastante espaço dependendo do tamanho.
Ativando overlay e br_netfilter
- OverlayFS: sistema de arquivos em camadas. Escreve por cima, sem mexer na base. Requisito para os containers (docs)
- br_netfilter: permite que o tráfego de uma bridge passe pelo netfilter, possibilitando a gerência das interfaces de rede dos containers (docs)
Ativando os módulos no boot:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
Carregando os módulos:
sudo modprobe overlay
sudo modprobe br_netfilter
Verificando os módulos:
lsmod | grep overlay
lsmod | grep br_netfilter
Parâmetros de rede
Por padrão, o Linux ignora o tráfego que passa por bridges. Só que o CNI (plugin de rede) do Kubernetes precisa ver esse tráfego pra funcionar.
Ativando o monitoramento do trafego
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipvip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
Ativando sem precisar reiniciar o ambiente:
sudo sysctl --system
Configuração dos repositórios necessários
Para o lab, foi necessário instalar as seguintes ferramentas:
- apt-transport-https: Utiliza repositórios HTTPS, garantindo downloads mais seguros
- ca-certificates: Gerencia certificados digitais para conexões HTTPS
- curl: Baixa arquivos e dados via terminal
- gpg e gnupg2: Gerenciam chaves criptográficas
- software-properties-common: Ferramenta para adicionar repositórios externos (
add-apt-repository
)
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg gnupg2 software-properties-common
Criando a pasta para armazenar as chaves GPG:
sudo mkdir -p /etc/apt/keyrings
Adicionando o repositório Docker no Ubuntu:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Adicionando o repositório do Kubernetes (v31):
sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v31/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null
Atualizando a base de pacotes:
sudo apt update
Instalar containerd
sudo apt install -y containerd.io
containerd.io: Runtime utilizado pelo Kubernetes para gerenciar e executar containers.
Configurar o containerd
O containerd
é o runtime de containers utilizado pelo Kubernetes para gerenciar a execução de containers em cada nó. Para garantir compatibilidade com o kubelet
, é necessário configurar o uso de cgroups com systemd
.
Passos:
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
[!NOTE]
Essa alteração é necessária para que okubelet
funcione corretamente com ocontainerd
em sistemas que utilizam osystemd
como gerenciador de serviços (como Ubuntu e Debian). Sem isso, o Kubernetes pode falhar ao iniciar os pods.
Na sequência, o serviço do containerd pode ser iniciado e habilitado com:
sudo systemctl restart containerd
sudo systemctl enable containerd
Resumo dos comandos
Todos os comandos desta etapa
# Verificar MAC address
ip link show
# Verificar UUID da máquina
cat /etc/machine-id
# Caso alguma máquina esteja com o mesmo ID
rm -f /etc/machine-id
systemd-machine-id-setup
# Verificar swap
swapon -s
# Desativar swap
sudo swapoff -a
# Remover swap do fstab
sudo sed -i '/swap/d' /etc/fstab
# (Opcional) Apagar o arquivo de swap se existir
sudo rm -f /swap.img
# Configuração para carregar módulos no boot
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# Carregando os modulos
sudo modprobe overlay
sudo modprobe br_netfilter
# Verificação dos módulos
lsmod | grep overlay
lsmod | grep br_netfilter
# Parâmetros para redirecionamento e inspeção de tráfego bridge
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipvip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
# Aplicar as configurações sem precisa reiniciar
sudo sysctl --system
Passos para os masters
Este lab foi montado com a versão 1.38.
Isso é importante, pois na hora de instalar os pacotes, precisamos garantir que isso seja cumprido corretamente para não ter nenhuma situação inesperada que se torne um impeditivo no futuro.
Componente | Versão | Detalhes |
---|---|---|
kube-apiserver | v3x | Todos os nós de controle (masters) devem rodar exatamente essa versão |
kube-controller-manager | v3x | Deve estar sincronizado com o kube-apiserver |
kube-scheduler | v3x | Também deve estar na mesma versão |
kubelet | v30.x ou v3x | Pode estar até uma versão menor atrás, mas nunca à frente |
kube-proxy | v30.x , v3x , v3x | Pode estar até uma versão acima ou abaixo |
kubectl | v30.x , v3x , v3x | Flexível para facilitar administração de diferentes clusters |
kubeadm | v3x | Use a mesma versão do cluster desejado (neste caso, v3x) |
Referência: Version skew policy | Kubernetes
Instalar e configurar os componentes principais do Kubernetes
sudo apt install -y kubectl
apt-mark hold kubelet
systemctl enable kubelet
- kubelet: Agente que roda em todos os nós, responsável por garantir que os containers estejam em execução conforme definido
Inicializando o cluster
Aqui é onde vem uma "pegada" minha para organização, o k8s no geral pede para baixar os arquivos e ir fazendo o kubectl apply -f qualquercoisa.yml
mas com isso o ambiente fica muito desorganizado, aqui vai uma proposta para melhorar isso.
mkdir -p k8s/base/calico \
k8s/base/metallb \
k8s/base/ippool \
k8s/base/networkpolicy \
k8s/base/rbac \
k8s/namespaces/devops/networkpolicy \
k8s/namespaces/devops/rbac \
k8s/namespaces/sistema-x-prod/networkpolicy \
k8s/namespaces/sistema-x-prod/rbac \
k8s/namespaces/modelo/networkpolicy \
k8s/namespaces/modelo/rbac \
k8s/scripts
Assim cada yml utilizado fica no seu lugar, de forma organizada.
Com isto, vamos começar a realizar o download dos ymls e preparar as coisas, aqui apenas fiz o download dos arquivos para depois aplicar as configurações no cluster
**CNI*Calico
curl -sSL https://raw.githubusercontent.com/projectcalico/calico/v27.0/manifests/calico.yaml -o "/etc/k8s/calico/calico.yaml"
CNIPool Calico
cat <<EOF > "/etc/k8s/ippool/default-ippool.yaml"
allation/api#operator.tigera.io/vInstallation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
# Configures Calico networking.
calicoNetwork:
ipPools:
name: default-ipv4-ippool
blockSize: 26
cidr: 10.240.0/16
encapsulation: VXLANCrossSubnet
natOutgoing: Enabled
nodeSelector: all()
MetalLB
curl -sSL https://raw.githubusercontent.com/metallb/metallb/v0.19/config/manifests/metallb-native.yaml -o "/etc/k8s/metallb/metallb-native.yaml
**Ingress*Nginx
curl -sSL https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v12/deploy/static/provider/cloud/deploy.yaml -o "/etc/k8s/ingress/nginx_deploy.yaml
Baixando as imagens para o containerd
kubeadm config images pull --cri-socket unix:///var/run/containerd/containerd.sock
Inicializando o cluster Atenção ao podnetwork, quando iniciar o calico, precisará utilizar a mesma subnet, caso contrario os pods não inicializarão.
kubeadm init --pod-network-cidr=10.240.0/16 --cri-socket unix:///var/run/containerd/containerd.sock --v=5
Configurando kubectl para conectar no cluster
mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
verificando cluster
kubectl get nodes
Configurando o cluster
kubectl get nodes
Passos para os workers
Os workers são os que menos dão trabalho, pois basicamente precisamos instalar o containerd, kubelet e kubeadm e depois incluir no cluster.